package com.authine.cloudpivot.web.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
import com.alibaba.xxpt.gateway.shared.client.http.GetClient;
import com.alibaba.xxpt.gateway.shared.client.http.PostClient;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.controller.login.HttpClientHelper;
import com.authine.cloudpivot.web.api.exception.PortalException;
import com.authine.cloudpivot.web.api.exception.ResultEnum;
import com.authine.cloudpivot.web.api.util.CookieUtil;
import com.irs.model.ZwddTokenUser;
import com.irs.utils.JwtTokenUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;


@Api(value = "浙政钉接口", tags = "浙政钉接口")
@Slf4j
@RequestMapping("/api/dashujuju")
@RestController
public class ZzdLoginController extends BaseController {

    @Value("${zzd.zhezhengdingHost}")
    private String zhezhengdingHost;
    @Value("${zzd.threeLevelDomainName}")
    private String threeLevelDomainName;
    @Value("${zzd.appKey}")
    private String appKey;
    @Value("${zzd.appSecret}")
    private String appSecret;
    @Value("${zzd.orgAppKey}")
    private String orgAppKey;
    @Value("${zzd.orgAppSecret}")
    private String orgAppSecret;

    private static final String SUCCESS = "success";
    private static final String TOKEN = "token";

    @GetMapping("/zzdLogin")
    public String zzdLogin(String code, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String ret = "";
        if (StringUtils.isEmpty(code)) {
            throw new Exception("code is null,please check login info!");
        }
        JSONObject userInfo;
        //判断code是否为json格式，如果是则为免登模式
        if (JSONObject.isValidObject(code)) {
            userInfo = this.getUserInfoByAccount(code);
        } else {
            //获取应用token
            String accessToken = getAccessToken();
            //根据token 获取用户信息
            userInfo = getUserInfo(accessToken, code);
        }
        ret = yunshuToken(userInfo,request);
        //写token
        String token = generateToken(userInfo);
        CookieUtil.writeCookie(response, "token", token, threeLevelDomainName);
        return ret;

    }

    /**
     * 免登
     * @param request
     * @return
     */
    @GetMapping("/freeLogin")
    public String freeLogin(HttpServletRequest request)  {
        String ret = "";
        //获取token
        String code = getRequestCookieValue(request);
        //获取用户信息
        JSONObject userInfo = getUserInfoByToken(code);
        ret = yunshuToken(userInfo,request);
        return ret;
    }

    /**
     * 获取request里面的cookie
     * @param request
     * @return
     */
    private String getRequestCookieValue(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (null == cookies || cookies.length == 0) {
            return StringUtils.EMPTY;
        }
        for (Cookie cookie : cookies) {
            if (TOKEN.equals(cookie.getName())) {
                return cookie.getValue();
            }
        }
        return StringUtils.EMPTY;
    }

    /**
     * 获取用户信息
     * @param token
     * @return
     */
    private JSONObject getUserInfoByToken(String token) {
        //判断token是否过期
        boolean verifyTokenResult = false;
        try {
            verifyTokenResult = JwtTokenUtil.verifyToken(token);
        } catch (Exception e) {
            log.error("token 过期异常:" + token, e);
        }
        if (!verifyTokenResult) {
            return null;
        }
        // 解析jwt用户信息
        ZwddTokenUser zwddTokenUser = null;
        try {
            zwddTokenUser = JwtTokenUtil.parseJwt(token);
        } catch (Exception e) {
            log.error("token 解析失败:" + token, e);
        }
        if (null == zwddTokenUser) {
            return null;
        }
        JSONObject userInfo = new JSONObject();
        userInfo.put("accountId", zwddTokenUser.getAccountId());
        userInfo.put("employeeCode", zwddTokenUser.getEmployeeCode());
        userInfo.put("tenantId", zwddTokenUser.getTenantId());
        return userInfo;
    }

    /**
     * 获取云枢token
     * @param userInfo
     * @param request
     * @return
     */
    private String yunshuToken(JSONObject userInfo, HttpServletRequest request) {
        //单点登陆
        List<UserModel> userModelList = super.getOrganizationFacade().getUsersByExtend("extend1", userInfo.getString("employeeCode"), "");
        if (!CollectionUtils.isEmpty(userModelList)) {
            UserModel userModel = userModelList.get(0);
            String username = userModel.getUsername();
            if (StringUtils.isNotBlank(username)) {
                return singlePointLogin(username, request);
            }
        }
        return StringUtils.EMPTY;
    }
    private String generateToken(JSONObject attributes) {
        ZwddTokenUser dingTokenUser = new ZwddTokenUser(Long.parseLong(String.valueOf(attributes.get("accountId"))),
                String.valueOf(attributes.get("employeeCode")), Long.parseLong(String.valueOf(attributes.get("tenantId"))));
        return JwtTokenUtil.createToken(dingTokenUser);
    }

    /**
     * 根据账号获取用户信息
     *
     * @param code
     * @return
     */
    private JSONObject getUserInfoByAccount(String code) {
        JSONObject jwtUserInfo = JSONObject.parseObject(code);
        JSONObject userDetailInfo = this.getUserDetailInfo(jwtUserInfo.getString("employeeCode"),
                jwtUserInfo.getString("tenantId"));
        jwtUserInfo.put("nickNameCn", userDetailInfo.getString("employeeName"));
        jwtUserInfo.put("lastName", userDetailInfo.getString("employeeName"));
        return jwtUserInfo;
    }

    /**
     * 获取用户详情
     *
     * @param employeeCode
     * @param tenantId
     * @return
     */
    private JSONObject getUserDetailInfo(String employeeCode, String tenantId) {
        //根据员工code获取员工详细信息
        ExecutableClient executableClient = ExecutableClient.getInstance();
        executableClient.setAccessKey(orgAppKey);
        executableClient.setSecretKey(orgAppSecret);
        executableClient.setDomainName(zhezhengdingHost);
        executableClient.setProtocal("https");
        executableClient.init();
        try {
            String api = "/mozi/employee/getEmployeeByCode";
            PostClient postClient = executableClient.newPostClient(api);
            //设置参数
            postClient.addParameter("employeeCode", employeeCode);
            postClient.addParameter("tenantId", tenantId);
            //调用API

            String apiResult = postClient.post();
            log.info("获取员工详情信息为:" + apiResult);
            JSONObject result = JSONObject.parseObject(apiResult);
            if (result.getBoolean(SUCCESS)) {
                return JSONObject.parseObject(
                        JSONObject.parseObject(JSONObject.parseObject(apiResult).getString("content")).getString(
                                "data"));
            } else {
                throw new Exception("获取员工详情信息异常，返回信息为：" + result.toJSONString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executableClient.destroy();
        }
        return null;
    }

    /**
     * 获取应用accessToken
     *
     * @return
     */
    private String getAccessToken() {
        ExecutableClient executableClient = ExecutableClient.getInstance();
        executableClient.setAccessKey(appKey);
        executableClient.setSecretKey(appSecret);
        executableClient.setDomainName(zhezhengdingHost);
        executableClient.setProtocal("https");
        executableClient.init();
        //executableClient要单例，并且使用前要初始化，只需要初始化一次
        try {
            String api = "/gettoken.json";
            GetClient getClient = executableClient.newGetClient(api);
            //设置参数
            getClient.addParameter("apikey", appKey);
            getClient.addParameter("apisecret", appSecret);
            //调用API
            String apiResult = getClient.get();
            log.info("获取access_token结果为:" + apiResult);
            JSONObject result = JSONObject.parseObject(apiResult);
            if (result.getBoolean(SUCCESS)) {
                return JSONObject.parseObject(JSONObject.parseObject(result.getString("content")).getString("data"))
                        .getString("accessToken");
            } else {
                throw new Exception(
                        JSONObject.parseObject(result.getString("content")).getString("responseMessage"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executableClient.destroy();
        }
        return null;
    }

    /**
     * 获取用户信息
     *
     * @param accessToken
     * @param code
     * @return
     */
    private JSONObject getUserInfo(String accessToken, String code) {
        ExecutableClient executableClient = ExecutableClient.getInstance();
        executableClient.setAccessKey(appKey);
        executableClient.setSecretKey(appSecret);
        executableClient.setDomainName(zhezhengdingHost);
        executableClient.setProtocal("https");
        executableClient.init();
        try {
            String api = "/rpc/oauth2/getuserinfo_bycode.json";
            PostClient postClient = executableClient.newPostClient(api);
            //设置参数
            postClient.addParameter("access_token", accessToken);
            postClient.addParameter("code", code);
            //调用API

            String apiResult = postClient.post();
            log.info("获取用户信息结果为:" + apiResult);
            JSONObject result = JSONObject.parseObject(apiResult);
            if (result.getBoolean(SUCCESS)) {
                return JSONObject.parseObject(
                        JSONObject.parseObject(JSONObject.parseObject(apiResult).getString("content")).getString(
                                "data"));
            } else {
                throw new Exception(
                        JSONObject.parseObject(result.getString("content")).getString("responseMessage"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executableClient.destroy();
        }
        return null;
    }

    private String singlePointLogin(String username, HttpServletRequest request) {
        String access_token = null;


        //模拟登陆，获取token
        //用户名密码模式登陆

        //配置登录失败，用配置端口重试一次
        String contextPath = request.getContextPath();
        String loginUrl = "http://127.0.0.1:8080" + (contextPath == null || contextPath.length() == 1 ? "" : contextPath) + "/login/password";
        String responseInfo = HttpClientHelper.getUsernamePasswordOauthToken(loginUrl, username, "Bio-San#21");
        if (StringUtils.isNotEmpty(responseInfo) && responseInfo.contains("access_token")) {
            Map map = JSON.parseObject(responseInfo, Map.class);
            access_token = (String) map.get("access_token");
            log.info("=====access_token:{}", access_token);
        } else {
            log.info("=====用户登录失败，用户:{}", username);
            throw new PortalException(ResultEnum.SERVER_ERROR.getErrCode(), "用户登录失败");
        }


        return access_token;
    }
}
